<template>
  <div class="warpper" id="warpper">
    <!-- 下拉提示语，定位到顶部 -->
    <div v-show="dropDown" class="topText">{{ refreshText }}</div>
    <div class="card" :ref="id">
      <ul ref="scroll_ul">
        <li v-for="(item, index) in data" :key="index">
          {{ item }}
        </li>
        <!-- 无数据提示 -->
        <li v-if="data.length === 0" class="noData">
          暂无需求
        </li>
      </ul>
    </div>
    <!-- 上推提示语，定位到底部 -->
    <div class="bottomTest" v-show="dropUp && !noMore">
      {{ moreText }}
    </div>
    <!-- 上推提示语，没更多时候显示，定位到底部 -->
    <div class="bottomTest" v-show="noMore && data.length > 0">
      没有更多需求
    </div>
  </div>
</template>

<script>
import BScroll from "better-scroll";
const UP_DISTANCE = 50; // 下拉偏移
const DWON_DISTANCE = 10; // 上推偏移
const WAPPER_OFFSET = 5; // 容器偏移
export default {
  props: {
    data: {
      //渲染数据
      type: Array,
      default: () => []
    },
    id: {
      type: String, //betterscroll父id，多例使用
      default: "scroll_wrapper"
    },
    total: {
      type: Number, // 总数
      default: 15
    }
  },
  data() {
    return {
      scroller: "", // betterscroll实例
      dropDown: false, // 下拉提示是否显示
      dropUp: false, // 上推提示是否显示
      noMore: false, // 没有更多提示是否显示
      refreshText: "", // 下拉提示语
      moreText: "" // 上推提示语
    };
  },
  mounted() {
    // 设置容器高度
    this.initWrapperHeight();
    // 初始化betterscroll实例
    this.init();
    // 给betterscroll增加监听事件
    this.action();
  },
  methods: {
    initWrapperHeight() {
      //视口高度
      let offsetHeight = document.documentElement.clientHeight;
      //tab高度
      let tabHeight = parseFloat(
        window.getComputedStyle(
          document.getElementsByClassName("vux-tab-container")[0]
        ).height
      );
      // 容器外的padding，margin
      let warpper = document.getElementById("warpper");
      let padding_margin =
        parseFloat(window.getComputedStyle(warpper).paddingTop) +
        parseFloat(window.getComputedStyle(warpper).paddingBottom) +
        parseFloat(window.getComputedStyle(warpper).marginTop) +
        parseFloat(window.getComputedStyle(warpper).marginBottom);

      // 容器
      let scroll_wrapper = this.$refs[this.id];
      let scroll_ul = this.$refs.scroll_ul;
      let warpperHeight =
        offsetHeight - tabHeight - padding_margin - WAPPER_OFFSET;
      scroll_ul.style.minHeight = warpperHeight + 1 + "px";
      scroll_wrapper.style.height = warpperHeight + "px";
    },
    init() {
      this.$nextTick(() => {
        if (!this.scroller) {
          this.scroller = new BScroll(this.$refs[this.id], {
            startY: 0,
            click: true,
            scrollX: false,
            probeType: 1,
            scrollY: true,
            click: true,
            bounce: {
              top: true,
              bottom: true,
              left: false,
              right: false
            }
          });
        } else {
          this.refresh();
        }
      });
    },
    action() {
      let that = this;
      this.$nextTick(() => {
        this.scroller.on("scroll", pos => {
          // 滚动中，如果下拉超限，则提示刷新
          if (pos.y > UP_DISTANCE) {
            that.dropDown = true;
            that.refreshText = "松开刷新";
          } else {
            that.dropDown = false;
          }

          // 滚动中，如果上推超限，则提示加载更多
          if (that.scroller.maxScrollY > pos.y + DWON_DISTANCE) {
            that.dropUp = true;
            that.moreText = "松开加载更多";
          } else {
            that.dropUp = false;
          }
        });

        this.scroller.on("touchEnd", pos => {
          // 离开事件中，如果下拉超限，则请求最新数据
          if (pos.y > UP_DISTANCE) {
            that.dropDown = true;
            that.refreshText = "刷新中...";
            that.scroller.disable();
            this.$emit("getNew");
            console.log(`${that.id}刷新`);
          }

          // 离开事件中，如果上推超限，则请求更多数据
          if (that.scroller.maxScrollY > pos.y + DWON_DISTANCE) {
            if (that.data.length !== 0 && that.data.length < that.total) {
              that.dropUp = true;
              that.moreText = "加载中...";
              that.scroller.disable();
              this.$emit("getMore");
              console.log(`${that.id}加载更多`);
            } else {
              that.refresh();
              that.noMore = true;
            }
          } else {
            that.dropUp = false;
            that.noMore = false;
          }
        });
      });
    },
    refresh() {
      this.$nextTick(() => {
        this.dropDown = this.dropUp = false;
        if (this.scroller) {
          console.log(this.id + "refresh");
          // 因为在下拉，上推中，防止多次操作，失效了scroller，在次激活
          this.scroller.enable();
          this.scroller.refresh();
        }
      });
    }
  },
  watch: {
    data: {
      immediate: true,
      deep: true,
      handler(val) {
        // 当数据变化时，容器大小需要重新计算高度
        this.refresh();
        if (val.length === 0) {
        }
      }
    }
  }
};
</script>

<style lang="less" scoped>
.warpper {
  position: relative;
  padding: 18px 0;
}
.topText {
  position: absolute;
  left: 0;
  top: 0;
  height: 18px;
  width: 100%;
  line-height: 18px;
  text-align: center;
  font-size: 13px;
  color: rgba(0, 0, 0, 0.5);
}
.bottomTest {
  position: absolute;
  left: 0;
  bottom: 0;
  height: 18px;
  width: 100%;
  line-height: 18px;
  text-align: center;
  font-size: 13px;
  color: rgba(0, 0, 0, 0.5);
}

.card {
  // height: 624px;
  box-sizing: border-box;
  overflow: hidden;
  ul {
    box-sizing: border-box;
    padding: 0 10px;
    li {
      list-style: none;
      height: 150px;
      text-align: center;
      line-height: 150px;
      border: 1px solid #ddd;
    }
    li.noData {
      height: 28px;
      width: 100%;
      line-height: 28px;
      text-align: center;
      font-size: 16px;
      color: rgba(0, 0, 0, 0.6);
      border: none;
    }
  }
}
</style>
